package com.luca.sl651server.server.jSerialComm;

import com.luca.sl651server.constant.FrameConstant;
import com.luca.sl651server.server.channel.JSerialCommChannel;
import com.luca.sl651server.server.channel.JSerialCommDeviceAddress;
import com.luca.sl651server.server.codec.NettyFrameDecoder;
import com.luca.sl651server.server.codec.NettyHeaderDelimiterFrameDecoder;
import com.luca.sl651server.server.config.NettyServerConfig;
import com.luca.sl651server.server.handler.NattyjSerialCommServerHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JSerialCommNattyServer {
    private static final Logger LOGGER = LoggerFactory.getLogger(JSerialCommNattyServer.class);
    private NettyServerConfig config;

    public JSerialCommNattyServer(NettyServerConfig config) {
        this.config = config;
    }

    public void run() {
//        LOGGER.info("开始查找端口号:");
        EventLoopGroup eventLoopGroup = null;
        try {
            eventLoopGroup = new OioEventLoopGroup();
            Bootstrap bootstrap = new Bootstrap();
            // SO_BACKLOG，未连接+已连接队列和的最大长度，超过长度后请求会被拒绝
            bootstrap.group(eventLoopGroup)
                    .channel(JSerialCommChannel.class)
                    .handler(new LoggingHandler(LogLevel.DEBUG))
                    .handler(new ChannelInitializer<JSerialCommChannel>() {
                        @Override
                        protected void initChannel(JSerialCommChannel jSerialCommChannel) throws Exception {
//                            if (config.isHeaderDelimiterFlag()) {
                                // 1、自定义头标识符包分割处理器，解决粘包分包，分割出一个完整数据包
                                jSerialCommChannel.pipeline().addLast(new NettyHeaderDelimiterFrameDecoder(FrameConstant.MAX_FRAME_LEN * 3,
                                        FrameConstant.HEADER_START_HEX));
//                            }
                            NattyjSerialCommServerHandler handler = new NattyjSerialCommServerHandler((new NettyFrameDecoder(config.isCrcVerifyFlag(),
                                    config.getHeaderDecoder(), config.getBodyDecoder())));
                            handler.setBizService(config.getBizService());
                            handler.setFrameEncoder(config.getFrameEncoder());
                            jSerialCommChannel.pipeline().addLast(handler);
                        }
                    });

            LOGGER.info("连接端口号：{}", config.getComPort());
            ChannelFuture cf = bootstrap.connect(new JSerialCommDeviceAddress(config.getComPort())).sync();
            if (cf.isSuccess()) {
                LOGGER.info("[SL651-2014] Serial COMM netty 水文协议通信服务启动成功");
            }
            cf.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (eventLoopGroup != null) {
                eventLoopGroup.shutdownGracefully();
            }
        }
    }
}
